package com.example.designpatterns.sington;
/**
 * 1) 单例模式保证了 系统内存中该类只存在一个对象，节省了系
 * 统资源，对于一些需
 * 要频繁创建销毁的对象，使用单例模式可以提高系统性能
 * 2) 当想实例化一个单例类的时候，必须要记住使用相应的获取对象
 * 的方法，而不是使
 * 用new
 * 3) 单例模式使用的场景：需要频繁的进行创建和销毁的对象、
 * 创建对象时耗时过多或
 * 耗费资源过多(即：重量级对象)，但又经常用到的对象、工具类
 * 对象、频繁访问数
 * 据库或文件的对象(比如数据源、session工厂等)
 */
public class SingleTonPatterns {

    public static void main(String[] args) {
        // ----------------------饿汉式01  静态成员---------------------------
        SingleTon instance1 = SingleTon.getInstance();
        SingleTon instance2 = SingleTon.getInstance();
        System.out.println(instance1==instance2);
        // ----------------------饿汉式02  静态代码快---------------------------
        SingleTonStatic singleTonStatic1 = SingleTonStatic.getInstance();
        SingleTonStatic singleTonStatic2 = SingleTonStatic.getInstance();
        System.out.println(singleTonStatic1==singleTonStatic2);
        // ----------------------懒汉试 03 （线程不安全的 ）---------------------------
        SingleTonLazy singleTonLazy1 = SingleTonLazy.getInstance();
        SingleTonLazy singleTonLazy2 = SingleTonLazy.getInstance();
        System.out.println(singleTonLazy1==singleTonLazy2);
        // ----------------------懒汉试 04 （线程安全但是效率太低 同步代码块）---------------------------
        SingleTonLazySync singleTonLazySync1 = SingleTonLazySync.getInstance();
        SingleTonLazySync singleTonLazySync2 = SingleTonLazySync.getInstance();
        System.out.println(singleTonLazySync1==singleTonLazySync2);

        // ----------------------懒汉试 05 （线程不安全安全 同步代码块）---------------------------
        SingleTonLazySyncMethod singleTonLazySyncMethod1 = SingleTonLazySyncMethod.getInstance();
        SingleTonLazySyncMethod singleTonLazySyncMethod2 = SingleTonLazySyncMethod.getInstance();
        System.out.println(singleTonLazySyncMethod1==singleTonLazySyncMethod2);

        // ----------------------懒汉试 06 （线程安全 双重检查机制， 推荐使用的方式）---------------------------
        SingleTonLazyCheck singleTonLazyCheck1 = SingleTonLazyCheck.getInstance();
        SingleTonLazyCheck singleTonLazyCheck2 = SingleTonLazyCheck.getInstance();
        System.out.println(singleTonLazyCheck1==singleTonLazyCheck2);
        // ----------------------懒汉试 07 （线程安全 静态内部内的方式）---------------------------
        SingleTonLazyInnerClass singleTonLazyInnerClass1 = SingleTonLazyInnerClass.getInstance();
        SingleTonLazyInnerClass singleTonLazyInnerClass2 = SingleTonLazyInnerClass.getInstance();
        System.out.println(singleTonLazyInnerClass1==singleTonLazyInnerClass2);
        // ----------------------枚举 08 （线程安全 枚举的方式）---------------------------
        SingleTonEnum singleTonEnum01 = SingleTonEnum.INSTANCE;
        SingleTonEnum singleTonEnum2 = SingleTonEnum.INSTANCE;;
        System.out.println(singleTonLazyInnerClass1==singleTonLazyInnerClass2);
        singleTonEnum01.say();

    }
}

//  枚举 08 （线程安全 枚举的方式）
 enum SingleTonEnum{
    INSTANCE;
    public void say(){
        System.out.println("hello");
    }


}

//  懒汉试 07 （线程安全 静态内部内的方式）
class SingleTonLazyInnerClass{
    private static volatile SingleTonLazyInnerClass singleTon;
    //私有化构造方法
    private  SingleTonLazyInnerClass(){
    }
    // 写一个静态内部内
    private static class  SingTonInstance{
        private static final SingleTonLazyInnerClass INSTANCE= new SingleTonLazyInnerClass();
    }
    //提供一个静态的公有方法，直接返回SingletonInstance.INSTANCE
    public static synchronized SingleTonLazyInnerClass getInstance() {
        return SingTonInstance.INSTANCE;
    }


}

//  懒汉试 06 （线程安全 双重检查机制， 推荐使用的方式）
class SingleTonLazyCheck{
    private static volatile SingleTonLazyCheck singleTon;
    //私有化构造方法
    private  SingleTonLazyCheck(){
    }
    // 提供一个静态的方法供外部调用
    public static SingleTonLazyCheck getInstance(){
        if (singleTon==null){
            synchronized (SingleTonLazyCheck.class){
                if (singleTon==null){ //如果第一个线程进来创建对象后 volatile 后刷新主内存的数据
                    singleTon = new SingleTonLazyCheck();
                }
            }
        }
        return singleTon;
    }
}

//  懒汉试 05 （线程不安全安全 同步代码块）
class SingleTonLazySyncMethod{
    private static  SingleTonLazySyncMethod singleTon;
    //私有化构造方法
    private  SingleTonLazySyncMethod(){
    }
    // 提供一个静态的方法供外部调用
    public static SingleTonLazySyncMethod getInstance(){
        if (singleTon==null){
            synchronized (SingleTonLazySyncMethod.class){
                singleTon = new SingleTonLazySyncMethod();
            }
        }
        return singleTon;
    }
}

//  懒汉试 04 （线程安全但是效率太低 同步代码块）
class SingleTonLazySync{
    private static  SingleTonLazySync singleTon;
    //私有化构造方法
    private  SingleTonLazySync(){
    }
    // 提供一个静态的方法供外部调用
    public static synchronized SingleTonLazySync getInstance(){
        if (singleTon==null){
            singleTon = new SingleTonLazySync();
        }
        return singleTon;
    }
}

 //  懒汉试 03 （线程不安全的 ）
 class SingleTonLazy{
     private static  SingleTonLazy singleTon;
     //私有化构造方法
     private  SingleTonLazy(){
     }
     // 提供一个静态的方法供外部调用
     public static SingleTonLazy getInstance(){
         if (singleTon==null){
             singleTon = new SingleTonLazy();
         }
         return singleTon;
     }
 }



// 饿汉式 01 静态变量
class SingleTon{
    private static final SingleTon singleTon = new SingleTon();

    //私有化构造方法
    private  SingleTon(){

    }
    // 提供一个静态的方法供外部调用
    public static SingleTon getInstance(){
        return singleTon;
    }

}

// 静态代码快模式 02
class SingleTonStatic{

    private static   SingleTonStatic singleTon = null;
    {
        singleTon = new SingleTonStatic();
    }

    //私有化构造方法
    private  SingleTonStatic(){

    }
    // 提供一个静态的方法供外部调用
    public static SingleTonStatic getInstance(){
        return singleTon;
    }


}

